<template>
  <div class="relative">
    <div
      class="handle-plan-btns"
      v-if="jsCookie.get('userID') == userID || !userID"
    >
      <el-popover
        v-if="hasParams"
        placement="top-start"
        title="分享"
        :width="200"
        trigger="hover"
        content="分享您的规划结果"
      >
        <template #reference>
          <el-button class="mr-2" @click="sharePlan">分享</el-button>
        </template>
      </el-popover>
      <el-popover
        placement="top-start"
        title="保存"
        :width="200"
        trigger="hover"
        content="将您的规划信息保存为pdf"
      >
        <template #reference>
          <el-button class="mr-2" @click="generatePdf">保存为pdf</el-button>
        </template>
      </el-popover>
      <template v-if="showSaveBtn && (!isHandle || hasParams)">
        <el-button type="success" @click="savePlan">保存规划</el-button>
        <el-button v-if="planID" type="info" @click="setBtnStatus(false)">
          取消
        </el-button>
        <el-button v-else type="danger" @click="notSave">不保存</el-button>
      </template>
      <template v-else-if="!isHandle || hasParams">
        <el-button type="primary" @click="setBtnStatus(true)">
          编辑规划
        </el-button>
      </template>
    </div>
    <div id="container"></div>
    <el-dialog
      v-model="shareDialog"
      align-center
      title="分享您的规划结果"
      width="600"
    >
      <div class="flex">
        <el-input v-model="shareLink" disabled />
        <el-button @click="copyLink">复制链接</el-button>
      </div>
    </el-dialog>

    <el-drawer v-model="pdfDrawer" size="90%" title="导出pdf" direction="rtl">
      <div id="pdf-content">
        <img :src="planImgUrl" class="h-auwo" />
      </div>
      <template #footer>
        <div style="flex: auto">
          <!-- <el-button @click="cancelClick">cancel</el-button> -->
          <el-button
            type="primary"
            @click="htmlToPDF('pdf-content', 'test pdf')"
            >导出</el-button
          >
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";
import G6 from "@antv/g6";
import jsCookie from "js-cookie";
import { splitStrFn } from "../../utils/splitStr";
import { usePlanAtlasHook } from "./hook";
import { htmlToPDF } from "../../utils/htmlToPdf";
import { useRoute } from "vue-router";

const route = useRoute();
const hasParams = Object.keys(route.query).length;

const props = defineProps(["data", "searchType", "params", "planID", "userID"]);
const emits = defineEmits(["resetPlanData"]);

const planImgUrl = ref("");

let zlGraph: any = null;

onMounted(() => {
  G6.registerNode(
    "icon-node",
    {
      options: {
        size: [60, 20],
        stroke: "#91d5ff",
        fill: "#91d5ff"
      },
      draw(cfg: any, group: any) {
        const styles = this.getShapeStyle(cfg);
        const { labelCfg = {} } = cfg;

        const w = styles.width;
        const h = styles.height;

        cfg.children &&
          group.addShape("text", {
            attrs: {
              ...labelCfg.style,
              x: 40 - w / 2,
              y: 47 - h / 2,
              r: 6,
              cursor: "pointer",
              text: cfg.collapsed ? "展开" : "收缩",
              textBaseline: "middle",
              width: w, //200,
              height: h, // 60
              textAlign: "center",
              fontSize: 8,
              fill: "blue"
            },
            name: "collapse-icon"
          });

        const keyShape = group.addShape("rect", {
          attrs: {
            ...styles,
            x: -w / 2,
            y: -h / 2
          }
        });

        /**
         * leftIcon 格式如下：
         *  {
         *    style: ShapeStyle;
         *    img: ''
         *  }
         */
        if (cfg.leftIcon) {
          const { style, img } = cfg.leftIcon;
          group.addShape("rect", {
            attrs: {
              x: 1 - w / 2,
              y: 1 - h / 2,
              width: 38,
              height: styles.height - 2,
              fill: "#8c8c8c",
              ...style
            }
          });

          group.addShape("image", {
            attrs: {
              x: 8 - w / 2,
              y: 8 - h / 2,
              width: 24,
              height: 24,
              img:
                img ||
                "https://g.alicdn.com/cm-design/arms-trace/1.0.155/styles/armsTrace/images/TAIR.png"
            },
            name: "image-shape"
          });
        }

        // 如果不需要动态增加或删除元素，则不需要 add 这两个 marker
        // group.addShape("marker", {
        //   attrs: {
        //     x: 40 - w / 2,
        //     y: 52 - h / 2,
        //     r: 6,
        //     stroke: "#2a79bf",
        //     cursor: "pointer",
        //     symbol: EXPAND_ICON
        //   },
        //   name: "add-item"
        // });

        group.addShape("text", {
          attrs: {
            x: 80 - w / 2,
            y: 47 - h / 2,
            cursor: "pointer",
            text: "删除",
            textBaseline: "middle",
            width: w, //200,
            height: h, // 60
            textAlign: "center",
            fontSize: 8,
            fill: "red"
          },
          visible: showSaveBtn.value,
          name: "remove-item"
        });

        if (cfg.label) {
          group.addShape("text", {
            attrs: {
              ...labelCfg.style,
              text: splitStrFn(cfg.label, 11),
              textBaseline: "middle",
              width: w, //200,
              height: h, // 60
              textAlign: "center",
              fontSize: 8,
              fill: "#fff"
            }
          });
        }

        return keyShape;
      },
      setState(name, value, item: any) {
        if (name === "collapsed") {
          const marker = item
            .get("group")
            .find((ele: any) => ele.get("name") === "collapse-icon");
          const text = value ? "展开" : "收缩";
          marker.attr("text", text);
        }
      },
      update: undefined
    },
    "rect"
  );

  G6.registerEdge("flow-line", {
    draw(cfg: any, group: any) {
      const startPoint = cfg.startPoint;
      const endPoint = cfg.endPoint;

      const { style } = cfg;
      const shape = group.addShape("path", {
        attrs: {
          stroke: style.stroke,
          endArrow: style.endArrow,
          path: [
            ["M", startPoint.x, startPoint.y],
            ["L", startPoint.x, (startPoint.y + endPoint.y) / 2],
            ["L", endPoint.x, (startPoint.y + endPoint.y) / 2],
            ["L", endPoint.x, endPoint.y]
          ]
        }
      });

      return shape;
    }
  });

  const defaultStateStyles = {
    hover: {
      stroke: "#1890ff",
      lineWidth: 2
    }
  };

  const defaultNodeStyle = {
    fill: "#91d5ff",
    stroke: "#40a9ff",
    radius: 5
  };

  const defaultEdgeStyle = {
    stroke: "#91d5ff"
    // endArrow: {
    //   path: "M 0,0 L 12, 6 L 9,0 L 12, -6 Z",
    //   fill: "#91d5ff",
    //   d: -20
    // }
  };

  const defaultLayout = {
    type: "compactBox",
    direction: "LR",
    getId: function getId(d: any) {
      return d.id;
    },
    getHeight: function getHeight() {
      return 16;
    },
    getWidth: function getWidth() {
      return 16;
    },
    getVGap: function getVGap() {
      return 40;
    },
    getHGap: function getHGap() {
      return 70;
    }
  };

  const defaultLabelCfg = {
    style: {
      fill: "#000",
      fontSize: 12
    }
  };

  const container: any = document.getElementById("container");

  const width = container.scrollWidth || 800;
  const height = container.scrollHeight || 500;

  const minimap = new G6.Minimap({
    size: [150, 100]
  });
  const graph = new G6.TreeGraph({
    container: "container",
    width,
    height,
    linkCenter: true,
    plugins: [minimap],
    modes: {
      default: ["drag-canvas", "zoom-canvas"]
    },
    defaultNode: {
      type: "icon-node",
      size: [120, 40],
      style: defaultNodeStyle,
      labelCfg: defaultLabelCfg
    },
    defaultEdge: {
      type: "cubic-horizontal",
      style: defaultEdgeStyle
    },
    nodeStateStyles: defaultStateStyles,
    edgeStateStyles: defaultStateStyles,
    layout: defaultLayout
  });

  // add image log
  graph.setTextWaterMarker(["透策"]);

  // tree data depth
  G6.Util.traverseTree(props.data, function (item: any) {
    if (item.depth > 0) {
      //collapsed为true时默认收起
      item.collapsed = true;
    }
  });

  graph.data(props.data);
  graph.render();
  graph.fitView();

  graph.on("node:mouseenter", (evt: any) => {
    const { item } = evt;
    graph.setItemState(item, "hover", true);
  });

  graph.on("node:mouseleave", (evt: any) => {
    const { item } = evt;
    graph.setItemState(item, "hover", false);
  });

  graph.on("node:click", (evt: any) => {
    const { item, target } = evt;
    const targetType = target.get("type");
    const name = target.get("name");

    // 增加元素
    if (targetType === "text") {
      const model = item.getModel();
      if (name === "add-item") {
        if (!model.children) {
          model.children = [];
        }
        const id = `n-${Math.random()}`;
        model.children.push({
          id,
          label: id.substr(0, 8),
          leftIcon: {
            style: {
              fill: "#e6fffb",
              stroke: "#e6fffb"
            },
            img: "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Q_FQT6nwEC8AAAAAAAAAAABkARQnAQ"
          }
        });
        graph.updateChild(model, model.id);
      } else if (name === "remove-item") {
        graph.removeChild(model.id);
        planData.value = graph.cfg.data;
      } else if (name === "collapse-icon") {
        evt.item.getModel().collapsed = !evt.item.getModel().collapsed;
        graph.setItemState(
          evt.item,
          "collapsed",
          evt.item.getModel().collapsed
        );
        graph.layout();
      } else {
        if (evt.item._cfg.id != 0) {
          window.open(
            `${location.origin}/detail?id=${evt.item._cfg.id}&searchType=${
              props.searchType ? props.searchType : "2"
            }`,
            "_blank"
          );
        }
      }
    }
  });

  if (typeof window !== "undefined")
    window.onresize = () => {
      if (!graph || graph.get("destroyed")) return;
      if (!container || !container.scrollWidth || !container.scrollHeight)
        return;
      graph.changeSize(container.scrollWidth, container.scrollHeight);
    };

  zlGraph = graph;
});

const generatePlanImg = () => {
  zlGraph.toFullDataURL((data: any) => {
    planImgUrl.value = data;
  });
};

const {
  savePlan,
  notSave,
  planData,
  showSaveBtn,
  shareDialog,
  shareLink,
  sharePlan,
  copyLink,
  generatePdf,
  pdfDrawer,
  isHandle
} = usePlanAtlasHook(props, emits, generatePlanImg);

const setBtnStatus = (flag: boolean) => {
  showSaveBtn.value = flag;

  zlGraph.render();
  zlGraph.fitView();
};
</script>

<style scoped lang="postcss">
#container,
#container2 {
  height: 80vh;
}

.handle-plan-btns {
  @apply absolute right-3 top-3 flex items-center;
  z-index: 99;
}

.side-bars {
  @apply absolute bottom-3 right-3;
  z-index: 99;
}

img {
  height: 100%;
}
</style>
